package com.zpp.common.redis.config;

import com.alibaba.fastjson2.JSON;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;


/**
 * Redis的JSON序列化器
 * 作用：实现将Java对象与字节数组之间的转换（用于Redis存储）
 */

public class JsonRedisSerializer<T> implements RedisSerializer<T> {


    //静态常量：默认字符集UTF-8，在字符串与字节数组相互转换时指定编码格式，避免中文乱码
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");


    // 泛型对应的Class对象，反序列化时需要知道目标对象的类型，通过该字段指定
    private Class<T> clazz;


    //构造方法
    public JsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }


    //序列化方法：将Java对象转换为字节数组（用于存储到Redis）
    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            // 如果对象为null，返回空字节数组（Redis通常用空数组表示null值）
            return new byte[0];
        }

        //用FastJSON将对象转为JSON字符串  将JSON字符串按UTF-8编码转为字节数组
        return JSON.toJSONString(t).getBytes(DEFAULT_CHARSET);
    }

    //反序列化方法：将字节数组转换为Java对象（从Redis读取后还原）
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            // 如果字节数组为空或长度为0，返回null（对应序列化时的null处理）
            return null;
        }

        // 1. 将字节数组按UTF-8编码转为JSON字符串
        String str = new String(bytes, DEFAULT_CHARSET);

        // 2. 用FastJSON将JSON字符串解析为clazz类型的对象（借助构造方法传入的Class对象确定目标类型）
        return JSON.parseObject(str, clazz);
    }
}
